package com.jet.goods.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jet.core.enums.CommonStatus;
import com.jet.core.exception.CustomException;
import com.jet.core.model.vo.PageVo;
import com.jet.core.result.ResultCode;
import com.jet.core.utils.IdUtil;
import com.jet.goods.domain.dto.UnitDto;
import com.jet.goods.domain.entity.GoodsUnit;
import com.jet.goods.domain.query.SpuQuery;
import com.jet.goods.domain.query.UnitQuery;
import com.jet.goods.domain.vo.SpuListVo;
import com.jet.goods.domain.vo.UnitVo;
import com.jet.goods.mapper.GoodsUnitMapper;
import com.jet.goods.service.IGoodsSpuService;
import com.jet.goods.service.IGoodsUnitService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-04
 */
@Service
public class GoodsUnitServiceImpl extends ServiceImpl<GoodsUnitMapper, GoodsUnit> implements IGoodsUnitService {

    private final IGoodsSpuService goodsSpuService;

    public GoodsUnitServiceImpl(IGoodsSpuService goodsSpuService) {
        this.goodsSpuService = goodsSpuService;
    }

    @Override
    public GoodsUnit create(long merchantNo, UnitDto dto) {
        if (existsByName(merchantNo, null, dto.getName())) {
            throw new CustomException(ResultCode.BAD_REQUEST, "单位名重复");
        }
        GoodsUnit entity = new GoodsUnit();
        entity.setId(IdUtil.generateLower());
        entity.setMerchantNo(merchantNo);
        entity.setName(dto.getName().trim());
        entity.setType(dto.getType());
        super.save(entity);
        return entity;
    }

    @Override
    public void edit(long merchantNo, String id, UnitDto dto) {
        if (existsByName(merchantNo, id, dto.getName())) {
            throw new CustomException(ResultCode.BAD_REQUEST, "单位名重复");
        }
        GoodsUnit entity = new GoodsUnit();
        entity.setId(id);
        entity.setName(dto.getName());
        entity.setType(dto.getType());
        super.updateById(entity);
    }

    private boolean existsByName(long merchantNo, String id, String name) {
        Wrapper<GoodsUnit> wrapper = new LambdaQueryWrapper<GoodsUnit>()
                .eq(GoodsUnit::getName, name)
                .and(x -> x.eq(GoodsUnit::getMerchantNo, merchantNo).or().eq(GoodsUnit::getMerchantNo, 0))
                .ne(StrUtil.isNotBlank(id), GoodsUnit::getId, id);
        return super.exists(wrapper);
    }

    @Override
    public void delete(long merchantNo, String id) {
        GoodsUnit entity = super.getById(id);
        if (entity == null) {
            throw new CustomException(ResultCode.BAD_REQUEST, "单位信息错误");
        }
        if (entity.getMerchantNo() == 0) {
            throw new CustomException(ResultCode.BAD_REQUEST, "系统预设单位信息不能删除");
        }
        SpuQuery spuQuery = new SpuQuery();
        spuQuery.setUnitId(id);
        List<SpuListVo> spus = goodsSpuService.list(merchantNo, spuQuery);
        if (!CollectionUtils.isEmpty(spus)) {
            throw new CustomException("无法删除使用中的单位信息");
        }
        super.removeById(id);
    }

    @Override
    public GoodsUnit findByName(long merchantNo, String name) {
        Wrapper<GoodsUnit> wrapper = new LambdaQueryWrapper<GoodsUnit>()
                .eq(GoodsUnit::getName, name)
                .and(x -> x.eq(GoodsUnit::getMerchantNo, merchantNo).or().eq(GoodsUnit::getMerchantNo, 0));
        return super.getOne(wrapper);
    }

    @Override
    public List<UnitVo> findAllByIds(long merchantNo, List<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<GoodsUnit> list = super.listByIds(ids);
        return list.stream().map(x -> {
            UnitVo vo = new UnitVo();
            BeanUtils.copyProperties(x, vo);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public PageVo<UnitVo> page(long merchantNo, String name, UnitQuery query) {
        Page<GoodsUnit> tempQuery = new Page<>(query.getPageIndex(), query.getPageSize());
        QueryWrapper<GoodsUnit> wrapper = new QueryWrapper<>();
        wrapper.eq("1", 1);
        wrapper.lambda().and(x -> x.eq(GoodsUnit::getMerchantNo, merchantNo).or().eq(GoodsUnit::getMerchantNo, 0))
                .like(StrUtil.isNotBlank(name), GoodsUnit::getName, name)
                .orderByDesc(GoodsUnit::getCreateTime);
        IPage<GoodsUnit> page = super.page(tempQuery, wrapper);
        List<UnitVo> vos = page.getRecords().stream().map(x -> {
            UnitVo vo = new UnitVo();
            BeanUtils.copyProperties(x, vo);
            return vo;
        }).collect(Collectors.toList());
        return PageVo.result(page, vos);
    }

    @Override
    public List<UnitVo> findAll(long merchantNo) {
        QueryWrapper<GoodsUnit> wrapper = new QueryWrapper<>();
        wrapper.eq("1", 1);
        wrapper.and(x -> x.eq("merchant_no", merchantNo).or().eq("merchant_no", 0));
        List<GoodsUnit> units = super.list(wrapper);
        return units.stream().map(x -> {
            UnitVo vo = new UnitVo();
            BeanUtils.copyProperties(x, vo);
            return vo;
        }).collect(Collectors.toList());
    }
}
